#pragma once
#include "ArrayQueue.h"

template <typename T>
class ConcurrentArrayQueue : public ArrayQueue<T>
{
private :
	LockHelper m_oLockHelper;
public :
	ConcurrentArrayQueue(int a_nMaxSize);
	~ConcurrentArrayQueue();

	virtual void offer(T a_oData);
	virtual T poll();
	virtual T peek();
	virtual bool canOffer();
	virtual bool canPoll();
	virtual int getDataCount();

};

template <typename T>
ConcurrentArrayQueue<T>::ConcurrentArrayQueue(int a_nSize) : ArrayQueue<T>(a_nSize)
{
}

template <typename T>
ConcurrentArrayQueue<T>::~ConcurrentArrayQueue()
{
}

template <typename T>
void ConcurrentArrayQueue<T>::offer(T a_oData) {

	m_oLockHelper.lock();
	ArrayQueue<T>::offer(a_oData);
	m_oLockHelper.unlock();
}

template <typename T>
T ConcurrentArrayQueue<T>::poll() {
 
	m_oLockHelper.lock();
	T polledData = ArrayQueue<T>::poll();
	m_oLockHelper.unlock();

	return polledData;
}

template <typename T>
T ConcurrentArrayQueue<T>::peek() {

	m_oLockHelper.lock();
	T peekedData = ArrayQueue<T>::peek();
	m_oLockHelper.unlock();

	return peekedData;
}

template <typename T>
bool ConcurrentArrayQueue<T>::canOffer() {
	m_oLockHelper.lock();
	bool bOfferable = ArrayQueue<T>::canOffer();
	m_oLockHelper.unlock();

	return bOfferable;
}

template <typename T>
bool ConcurrentArrayQueue<T>::canPoll() {

	m_oLockHelper.lock();
	bool bPollable = ArrayQueue<T>::canPoll();
	m_oLockHelper.unlock();

	return bPollable;
}

template <typename T>
int ConcurrentArrayQueue<T>::getDataCount() {

	m_oLockHelper.lock();
	int dataCount = ArrayQueue<T>::getDataCount();
	m_oLockHelper.unlock();

	return dataCount;
}